<template>
  <div class="area" ref="parent">
      <svg class="area-area">

      </svg>
  </div>
</template>

<script>
import d3 from "d3";
import Debug from "debug";
const dbg = Debug("Area");
dbg.enabled = true;

export default {
  data() {
    const dataPoints = (function() {
      var arr = [];
      for (let i = 1; i <= 5; i++) {
        arr.push((Math.random() * 1000) % 100 - 50);
      }
      return arr;
    })();
    return {
      dataPoints
    };
  },
  mounted() {
    const parent = d3.select(this.$refs["parent"]);
    const outer_width = 1920,outer_height=200;
    const padding = { top: 10, bottom: 30, left: 40, right: 40 };
    const height = outer_height-padding.top-padding.bottom,
      width = outer_width-padding.left-padding.right;
    const svg = parent.select("svg.area-area");
    svg
      .attr("width", width + padding.right + padding.left)
      .attr("height", height + padding.top + padding.bottom);
    const xScale = d3.scale
      .linear()
      .domain([0, this.dataPoints.length - 1])
      .range([0, width]);
    const yScale = d3.scale
      .linear()
      .domain(
        function() {
          var max = d3.max(this.dataPoints);
          var min = d3.min(this.dataPoints);
          var length = max - min;
          return [max + length * 0.1, min - length * 0.2];
        }.bind(this)()
      )
      .range([0, height]);
    +(function drawAxis() {
      var yAxis = d3.svg
        .axis()
        .scale(yScale)
        .orient("left");
      svg
        .append("g")
        .classed("axis", true)
        .attr(
          "transform",
          "translate(" + padding.left + "," + padding.top + ")"
        )
        .call(yAxis);
      var xAxis = d3.svg
        .axis()
        .scale(xScale)
        .orient("bottom");
      svg
        .append("g")
        .classed("axis", true)
        .attr(
          "transform",
          "translate(" + padding.left + "," + (padding.top + height) + ")"
        )
        .call(xAxis);
    })();
    var areaGen = function drawArea() {
      var areaGen = d3.svg
        .area()
        .x((d, i) => {
          // debugger
          return padding.left + xScale(i);
        })
        .y0(d => {
          //   debugger;
          return yScale(d) + padding.top;
        })
        .y1(d => {
          return padding.top + height;
        })
        .interpolate("monotone");
      svg
        .selectAll("path.area")
        .data([this.dataPoints])
        .enter()
        .append("path")
        .classed("area", true)
        .attr("d", d => {
          return areaGen(d);
        })
        .attr("fill", d => {
          return "#FF0080";
        })
        .attr("stroke", "#FF0080");
      return areaGen;
    }.bind(this)();

    +function drawCircles() {
      svg
        .selectAll("circle.data-point")
        .data(this.dataPoints)
        .enter()
        .append("circle")
        .classed("data-point", true)
        .attr("cx", (d, i) => {
          return padding.left + xScale(i);
        })
        .attr("cy", d => {
          return yScale(d) + padding.top;
        })
        .attr("r", d =>
          d3.scale
            .linear()
            .domain([d3.min(this.dataPoints), d3.max(this.dataPoints) + 1])
            .range([6, 20])(d)
        )
        .attr("raw", d => d);
    }.bind(this)();
    +(function drawRectForMouseEvents() {
      var rect = svg
        .append("rect")
        .attr("class", "overlay")
        .attr("x", padding.left)
        .attr("y", padding.top)
        .attr("width", width)
        .attr("height", height);
      var focusCircle = (function() {
        var g = svg
          .append("g")
          .classed("focus-circle", true)
          .style("display", "none");
        g.append("circle").attr("r", 4.5);
        g
          .append("text")
          .attr("dx", 10)
          .attr("dy", "1em");
        return g;
      })();
      var focusLine = svg
        .append("g")
        .classed("focus-line", true)
        .style("display", "none");
      var focusPointX = undefined;
      const that = this;
      rect
        .on("mouseover", function() {
          focusCircle.style("display", null);
          focusLine.style("display", null);
        })
        .on("mouseout", function() {
          focusCircle.style("display", "none");
          // focusLine.style("display", "none");
        })
        .on("mousemove", function() {
          var mouseRect = d3.mouse(this);
          // var mouseSvg = d3.mouse(this.parentNode);
          /*
          神奇的是,d3.mouse(this<--svg:rect)和d3.mouse(this.parentNode<--svg:svg)的结果是一样的
          */
          // var mouseDiv = d3.mouse(this.parentNode.parentNode);
          // dbg("%j",{mouseX,mouseY,mouseSvg,mouseDiv});
          var mouseX = mouseRect[0] - padding.left;
          var mouseY = mouseRect[1] - padding.top;
          var x = xScale.invert(mouseX);
          var y = yScale.invert(mouseY);
          var closestX = Math.round(x);
          if (!focusPointX || focusPointX != closestX) {
            focusPointX = closestX;
            +(function reDrawLine() {
              focusLine.html('');
              focusLine
                .selectAll("path.focus")
                .data([closestX])
                .enter()
                .append("path")
                .classed("focus", true)
                .attr("d", data => {
                  var x = xScale(closestX)+padding.left;
                  var y = yScale(that.dataPoints[closestX])+padding.top;
                  return d3.svg.line()([
                    [padding.left, y],
                    [x,y],
                    [x, padding.top + height]
                  ]);
                });
            }.bind(this))();
          }
        });
    }.bind(this))();
  }
};
</script>

<style lang="scss">
.area {
  svg.area-area {
    border: 1px solid;
    path.area {
      fill-opacity: 0.25;
    }
    circle.data-point {
      fill: white;
      fill-opacity: 0.5;
      stroke: #ff0080;
    }
    g.axis {
      path,
      line {
        fill: none;
        stroke: hsla(330, 113%, 26%, 1);
        shape-rendering: crispEdges;
      }
      text {
        fill: black;
        font-size: 11px;
        font-weight: bold;
        font-family: sans-serif;
      }
    }
    g.focus-line{

      path.focus{
        fill: none;
        stroke: black;
        stroke-dasharray: 5,6.7;
        stroke-width: 1px;
      }
    }
    rect.overlay {
      fill-opacity: 0.0;
      pointer-events: all;
    }
  }
}
</style>
